{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([5, 5])\n",
      "torch.Size([9, 25])\n",
      "torch.Size([9, 9])\n"
     ]
    }
   ],
   "source": [
    "im=5\n",
    "k=3\n",
    "s=1\n",
    "out_width=im-k+1\n",
    "img = torch.randn(5,5)\n",
    "kernel = torch.randn(3,3)\n",
    "zeros= torch.zeros(5,5)\n",
    "KERNEL = torch.zeros(out_width**2,im**2)\n",
    "PIXEL = torch.zeros(out_width**2,k**2)\n",
    "print(zeros.shape)\n",
    "for i in range(0,out_width):\n",
    "    for j in range(0,out_width):\n",
    "        zeros[i:k+i,j:k+j]=kernel\n",
    "        #print(zeros.view(25))\n",
    "        KERNEL[i*out_width+j,:] = zeros.view(25)\n",
    "        zeros= torch.zeros(5,5)\n",
    "        #print(img[i:k+i,j:k+j].reshape(9))\n",
    "        PIXEL[i*out_width+j,:] =img[i:k+i,j:k+j].reshape(9) \n",
    "print(KERNEL.shape)\n",
    "print(PIXEL.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([25, 9])\n"
     ]
    }
   ],
   "source": [
    "print(KERNEL.t().shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[2.7633, 3.8436, 6.3206, 2.2015, 4.3310, 6.6124, 2.1051, 0.3107, 1.7178]])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img.reshape(1,25).mm(KERNEL.t())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[2.7633, 3.8436, 6.3206, 2.2015, 4.3310, 6.6124, 2.1051, 0.3107, 1.7178]])"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "kernel.reshape(1,9).mm(PIXEL.t())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Z = sigmoid(O)\n",
    "# O = conv(img,kernel)\n",
    "# loss = 0.5*(Z-Y)^2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "O=img.reshape(1,25).mm(KERNEL.t())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "Z = torch.sigmoid(O)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[0.9462, 0.9784, 0.9980, 0.8866, 0.9859, 0.9985, 0.8962, 0.4552, 0.8393]]),\n",
       " tensor([0, 0, 1, 0, 0, 0, 0, 0, 0]))"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Z,Y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [],
   "source": [
    "Y=torch.nn.functional.one_hot(torch.tensor(2),9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "E = Z-Y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(6.4364)"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(E**2).sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DLoss/Dimg = DLoss/DZ x DZ/DO x DO/Dimg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([1, 25])"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "((E*Z*(1-Z)).mm(KERNEL)).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([9, 25])"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "KERNEL.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DLoss/Dkernel = DLoss/DZ x DZ/DO x DO/Dkernel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [],
   "source": [
    "Dkernel=E*Z*(1-Z).mm(PIXEL)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.9829, 0.9789, 1.0000],\n",
       "        [1.0133, 0.9888, 0.9866],\n",
       "        [1.0083, 1.0015, 1.0087]])"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "kernel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "kernel = kernel-0.1* Dkernel.view(3,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.9242, 0.9060, 1.0001],\n",
       "        [1.0600, 0.9496, 0.9404],\n",
       "        [1.0379, 1.0059, 1.0394]])"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "kernel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([9, 25])\n",
      "torch.Size([9, 9])\n"
     ]
    }
   ],
   "source": [
    "for i in range(0,out_width):\n",
    "    for j in range(0,out_width):\n",
    "        zeros[i:k+i,j:k+j]=kernel\n",
    "        #print(zeros.view(25))\n",
    "        KERNEL[i*out_width+j,:] = zeros.view(25)\n",
    "        zeros= torch.zeros(5,5)\n",
    "        #print(img[i:k+i,j:k+j].reshape(9))\n",
    "        PIXEL[i*out_width+j,:] =img[i:k+i,j:k+j].reshape(9) \n",
    "print(KERNEL.shape)\n",
    "print(PIXEL.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:python3.6.7]",
   "language": "python",
   "name": "conda-env-python3.6.7-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
